home *** CD-ROM | disk | FTP | other *** search
- /*
- * This routine is derived from BSD4.3 code,
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- */
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)tmpnam.c 4.5 (Berkeley) 6/27/88";
- #endif /* LIBC_SCCS and not lint */
- /*----------------------------------------------------------------------
- Return a unique file name in a given directory. This is not quite
- the same as the usual tempnam() function, though it is very similar.
- We want it to use the TMP environment variable only if dir is NULL,
- instead of using TMP regardless if it is set.
-
- Args: dir -- The directory to create the name in
- prefix -- Prefix of the name
-
- Result: Malloc'd string equal to new name is returned. It must be free'd
- by the caller. Returns the string on success and NULL on failure.
- ----*/
- char *
- temp_nam(dir, prefix)
- char *dir, *prefix;
- {
- struct stat buf;
- char *f, *name;
- char *our_mktemp();
-
- if (!(name = malloc((unsigned int)MAXPATHLEN)))
- return((char *)NULL);
-
- if (!dir && (f = getenv("TMPDIR")) && !stat(f, &buf) &&
- (buf.st_mode&S_IFMT) == S_IFDIR &&
- !can_access(f, WRITE_ACCESS|EXECUTE_ACCESS)) {
- (void)strcpy(name, f);
- goto done;
- }
-
- if (dir && !stat(dir, &buf) &&
- (buf.st_mode&S_IFMT) == S_IFDIR &&
- !can_access(dir, WRITE_ACCESS|EXECUTE_ACCESS)) {
- (void)strcpy(name, dir);
- goto done;
- }
-
- #ifndef P_tmpdir
- #define P_tmpdir "/usr/tmp"
- #endif
- if (!stat(P_tmpdir, &buf) &&
- (buf.st_mode&S_IFMT) == S_IFDIR &&
- !can_access(P_tmpdir, WRITE_ACCESS|EXECUTE_ACCESS)) {
- (void)strcpy(name, P_tmpdir);
- goto done;
- }
-
- if (!stat("/tmp", &buf) &&
- (buf.st_mode&S_IFMT) == S_IFDIR &&
- !can_access("/tmp", WRITE_ACCESS|EXECUTE_ACCESS)) {
- (void)strcpy(name, "/tmp");
- goto done;
- }
- free((void *)name);
- return((char *)NULL);
-
- done:
- if(*(f = &name[strlen(name) - 1]) != '/')
- *++f = '/';
-
- f++;
- if (prefix)
- sstrcpy(&f, prefix);
-
- sstrcpy(&f, "XXXXXX");
- return(our_mktemp(name));
- }
-
-
- /*
- * This routine is derived from BSD4.3 code,
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * We use this instead of mktemp() since we know of at least one stupid
- * mktemp() (AIX3.2) which breaks things.
- */
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)mktemp.c 5.7 (Berkeley) 6/27/88";
- #endif /* LIBC_SCCS and not lint */
-
- static
- _gettemp(as)
- char *as;
- {
- extern int errno;
- register char *start, *trv;
- struct stat sbuf;
- unsigned pid;
-
- pid = (unsigned)getpid();
-
- /* extra X's get set to 0's */
- for (trv = as; *trv; ++trv);
- while (*--trv == 'X') {
- *trv = (pid % 10) + '0';
- pid /= 10;
- }
-
- /*
- * check for write permission on target directory; if you have
- * six X's and you can't write the directory, this will run for
- * a *very* long time.
- */
- for (start = ++trv; trv > as && *trv != '/'; --trv);
- if (*trv == '/') {
- *trv = '\0';
- if (stat(as, &sbuf) || !(sbuf.st_mode & S_IFDIR))
- return(0);
- *trv = '/';
- }
- else if (stat(".", &sbuf) == -1)
- return(0);
-
- for (;;) {
- if (stat(as, &sbuf))
- return(errno == ENOENT ? 1 : 0);
-
- /* tricky little algorithm for backward compatibility */
- for (trv = start;;) {
- if (!*trv)
- return(0);
- if (*trv == 'z')
- *trv++ = 'a';
- else {
- if (isdigit(*trv))
- *trv = 'a';
- else
- ++*trv;
- break;
- }
- }
- }
- /*NOTREACHED*/
- }
-
- char *
- our_mktemp(as)
- char *as;
- {
- return(_gettemp(as) ? as : (char *)NULL);
- }
-
-
-